package cn.yuanqiao.archive.wenjianzhengli.service.impl;

import cn.yuanqiao.archive.appManager.domain.*;
import cn.yuanqiao.archive.appManager.mapper.*;
import cn.yuanqiao.archive.appManager.service.ITenantSysConfigService;
import cn.yuanqiao.archive.appManager.service.ITenantSysDictTypeService;
import cn.yuanqiao.archive.danganzhengli.domain.ImportArchiveLog;
import cn.yuanqiao.archive.danganzhengli.service.IImportArchiveLogService;
import cn.yuanqiao.archive.webservice.utils.XMLtoJsonUtils;
import cn.yuanqiao.archive.wenjianzhengli.mapper.TenantYqdaFolderMapper;
import cn.yuanqiao.archive.wenjianzhengli.service.IDaImportService;
import cn.yuanqiao.archive.wenjianzhengli.utils.UploadDAO;
import cn.yuanqiao.archive.wenjianzhengli.utils.UploadDataListener;
import cn.yuanqiao.common.enums.BusinessBehavior;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.util.BusinessBehaviorUtil;
import cn.yuanqiao.common.utils.DateUtils;
import cn.yuanqiao.common.utils.SnowflakeIdGenerator;
import cn.yuanqiao.common.utils.StringUtils;
import cn.yuanqiao.common.utils.file.FileTypeUtils;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.common.core.domain.model.LoginUser;
import cn.yuanqiao.system.service.ISysDeptService;
import cn.yuanqiao.system.service.ISysUserService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.io.FileUtils;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zjj
 * @date 2023/6/30
 */
@Service
public class DaImportServiceImpl implements IDaImportService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private TenantCategoryMapper categoryMapper;
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;
    @Autowired
    private ITenantSysDictTypeService sysDictTypeService;
    @Autowired
    private TenantMdataListMapper mdataListMapper;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private ArchiveMapper archiveMapper;

    @Autowired
    private ITenantSysConfigService sysConfigService;

    @Autowired
    private TenantYqdaMapper yqdaMapper;
    @Autowired
    private TenantYqdaFolderMapper yqdaFolderMapper;
    @Autowired
    private TenantYqFolderMapper folderMapper;
    @Autowired
    private TenantCodeListMapper codeListMapper;
    @Autowired
    private TenantYqItemMapper itemMapper;
    @Autowired
    private IImportArchiveLogService importArchiveLogService;

    @Override
    public UploadDAO getTitle(Long categoryId, Integer type, MultipartFile file) throws Exception{
        String extension = FileTypeUtils.getExtension(file);
        UploadDAO uploadDAO = new UploadDAO(); //解析入库在这里面完成
        if("xls".equals(extension) || "xlsx".equals(extension) ){
            uploadDAO.setType(0); //只解析表头
            EasyExcel.read(file.getInputStream(), new UploadDataListener(uploadDAO)).sheet().doRead();
        }else {
            throw new ServiceException("文件格式错误！");
        }
        return uploadDAO;
    }

    @Override
    public UploadDAO upload(JSONObject data, MultipartFile file) throws Exception {
        //{"categoryId":"123","type":"1","itemId":"-1","folderId":"-1",
        // "colNames":[{"xlsNum":"0","xlsName":"标题","name":"TITLE","showType":"1"},{"xlsNum":"1","xlsName":"保管期限","name":"BGQX","showType":"3"}]}

        if(!data.containsKey("categoryId") || StringUtils.isEmpty(data.getString("categoryId"))
                && !data.containsKey("type") || StringUtils.isEmpty(data.getString("type"))
                && !data.containsKey("colNames") || StringUtils.isEmpty(data.getString("colNames"))
                && !data.containsKey("state") || StringUtils.isEmpty(data.getString("state"))
                && !data.containsKey("jsType") || StringUtils.isEmpty(data.getString("jsType")))
        {
            throw new ServiceException("参数错误！");
        }
        TenantCategory category = categoryMapper.selectTenantCategoryByID(data.getLong("categoryId"),new TenantCategory().getTableName());
        if(category.getType() == 3 && data.getInteger("type") == 1
                && (!data.containsKey("itemId") || StringUtils.isEmpty(data.getString("itemId"))))
        {
            data.put("itemId",null);
            //throw new ServiceException("参数错误！");
        }
        if((category.getType() == 3 || category.getType() == 1) && data.getInteger("type") == 0
                && (!data.containsKey("folderId") || StringUtils.isEmpty(data.getString("folderId"))))
        {
            data.put("folderId",null);
            //throw new ServiceException("参数错误！");
        }

        UploadDAO uploadDAO = new UploadDAO(); //解析入库在这里面完成
        String extension = FileTypeUtils.getExtension(file);
        if("xls".equals(extension) || "xlsx".equals(extension) ){
            long beginTime = System.currentTimeMillis();
            LoginUser user = SecurityUtils.getLoginUser();
            uploadDAO.setType(1); //解析入库
            uploadDAO.setLoginUser(user);
            uploadDAO.setCategory(category);  //门类
            uploadDAO.setSqlSessionTemplate(sqlSessionTemplate);  //数据连接
            uploadDAO.setSysDictTypeService(sysDictTypeService); // 字典
            uploadDAO.setUserService(userService);
            uploadDAO.setDeptService(deptService);
            uploadDAO.setArchiveMapper(archiveMapper);
            uploadDAO.setData(data);
            uploadDAO.setCreateTime(DateUtils.getTime());
            TenantMdataList mdataList = new TenantMdataList();
            mdataList.setType(data.getInteger("type"));
            uploadDAO.setMdataList(mdataListMapper.selectNotEmptyDefaultByCategoryId(mdataList,data.getLong("categoryId"),new TenantCategory().getTableName()));
            EasyExcel.read(file.getInputStream(), new UploadDataListener(uploadDAO)).sheet().doRead();
            long endTime = System.currentTimeMillis();
            uploadDAO.setTime(endTime - beginTime);
        }
        return uploadDAO;
    }

    @Override
    @Transactional
    public String uploadXml(Long categoryId,String type, MultipartFile file) {
        int num = 0;
        StringBuffer msg = new StringBuffer();
        try {
            String path = sysConfigService.selectConfigByKey("YQ_MNT")+ File.separator+"otherData";
            //String path = "E://zjj";
            File file1 = new File(path);
            if(!file1.exists()){
                file1.mkdirs();
            }
            file1 = new File(file1.getAbsolutePath()+File.separator+new Date().getTime()+".xml");
            file.transferTo(file1);
            TenantCategory category = categoryMapper.selectTenantCategoryByID(categoryId,new TenantCategory().getTableName());
            com.alibaba.fastjson2.JSONObject archiveData = XMLtoJsonUtils.startXMLToJSON(file1);
            JSONArray array = new JSONArray();
            if(archiveData.get("RECORD") instanceof com.alibaba.fastjson2.JSONObject){
                array.add(archiveData.get("RECORD"));
            }else if(archiveData.get("RECORD") instanceof JSONArray){
                array = archiveData.getJSONArray("RECORD");
            }
            logger.info(array.toJSONString());
            num = saveData(array,type,category,"2","3",msg);
        }catch (Exception e){
            logger.error(e.getMessage(),e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚事务
        }

        return "导入成功"+num+"条;"+msg.toString();
    }

    @Override
    public String uploadTxt(Long categoryId, String type, MultipartFile file,String fileType) {
        int num = 0;
        StringBuffer msg = new StringBuffer();
        try {
            String path = sysConfigService.selectConfigByKey("YQ_MNT")+File.separator+"otherData";
            //String path = "E://zjj";
            File file1 = new File(path);
            if(!file1.exists()){
                file1.mkdirs();
            }
            file1 = new File(file1.getAbsolutePath()+File.separator+new Date().getTime()+".txt");
            file.transferTo(file1);
            TenantCategory category = categoryMapper.selectTenantCategoryByID(categoryId,new TenantCategory().getTableName());

            //导入记录
            Date start = new Date();
            ImportArchiveLog importArchiveLog = new ImportArchiveLog();
            importArchiveLog.setCreateTime(new Date());
            importArchiveLog.setFileName(file.getOriginalFilename());

            if("txt".equals(fileType)){
                importArchiveLog.setFilePath(file1.getAbsolutePath());
            }else if("mdb".equals(fileType)){
                File file2 = new File(file1.getParent()+File.separator+new Date().getTime()+".mdb");
                FileUtils.copyFile(file1,file2);
                importArchiveLog.setFilePath(file2.getAbsolutePath());
            }
            importArchiveLog.setSourceType(1);
            importArchiveLog.setCategoryId(category.getId());
            importArchiveLog.setType(category.getType());

            JSONArray array = new JSONArray();
            com.alibaba.fastjson.JSONObject object = new com.alibaba.fastjson.JSONObject();
            List<String> list = Files.readAllLines(Paths.get(file1.getAbsolutePath()), StandardCharsets.UTF_8);
            for(int i = 0;i<list.size();i++){
                String titleStr = list.get(i);
                String [] title = titleStr.split("\",");
                if(i == 0){
                    //表头
                    for(int x = 0;x<title.length;x++){
                        object.put(String.valueOf(x),title[x].replaceAll("\"","").toUpperCase());
                    }
                }else {
                    com.alibaba.fastjson.JSONObject data = new com.alibaba.fastjson.JSONObject();
                    for(int x = 0;x<title.length;x++){
                        String val = title[x].replaceAll("\"","");
                        if(!"null".equals(val) && StringUtils.isNotEmpty(val)){
                            data.put(object.getString(String.valueOf(x)),val);
                        }
                    }
                    array.add(data);
                }
            }
            logger.info(array.toJSONString());
            if("txt".equals(fileType)){
                num = saveData(array,type,category,"2","3",msg);
            }else if("mdb".equals(fileType)){
                num = saveData(array,type,category,"6","12",msg);

                Date end = new Date();
                importArchiveLog.setResult("导入成功"+ num + "条");
                importArchiveLog.setMsg("耗时:"+DateUtils.longTileString(end.getTime() - start.getTime()));
                importArchiveLogService.insertImportArchiveLog(importArchiveLog);
            }



        }catch (Exception e){
            logger.error(e.getMessage(),e);
            try {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚事务
            }catch (Exception e1){
                logger.error(e1.getMessage(),e1);
            }
        }
        return "导入成功"+num+"条;"+msg.toString();
    }

    private int saveData(JSONArray array,String type,TenantCategory category,String jsType,String state,StringBuffer msg){
        int num = 0;

        //验证规则
        //TenantMdataList select = new TenantMdataList();
        //select.setGroupId(category.getGroupId());
        //select.setType("f".equals(type) ? 0:(("v".equals(type) ? 1:3)));
        //List<TenantMdataList> mdataLists = mdataListMapper.getListByVerificationRules(select);

        for(int i = 0;i<array.size();i++){
            com.alibaba.fastjson2.JSONObject object = array.getJSONObject(i);
            Map<String,String> map = new HashMap<>();
            for(String key:object.keySet()){
                if(!"ID".equals(key.toUpperCase()) && !"ORDER_NUM".equals(key.toUpperCase()) && !"null".equals(object.getString(key))){
                    map.put(key.toUpperCase(),object.getString(key));
                }
            }
            Long id = SnowflakeIdGenerator.generateId();
            map.put("ID", String.valueOf(id));
            map.put("JS_TYPE",jsType);
            map.put("STATE",state);

            /*Boolean bl = false;
            for(TenantMdataList mdata:mdataLists){
                try {
                    ArchiveUtils.VerificationRules(map.get(mdata.getFieldName()),mdata);
                }catch (ServiceException e){
                    msg.append(e.getMessage()+"已跳过;");
                    bl = true;
                    continue;
                }
            }
            if(bl){
                continue;
            }*/

            if("f".equals(type)){
                if(StringUtils.isNotEmpty(map.get("DH"))){
                    Integer count = yqdaMapper.getCountByCol("DH",map.get("DH"),category.getFileTableName());
                    if(count>0){
                        msg.append("档号重复:"+map.get("DH")+"已跳过;");
                        continue;
                    }
                }

                TenantYqda yqda = new TenantYqda();
                yqda.setColNames(map);
                //插入分表
                yqda.setTableName(category.getFileTableName());
                yqdaMapper.insertYqdaDisperse(yqda);
                //插入主表
                String ID = map.get("ID");
                map.remove("ID");
                map.put("DA_ID",ID);
                map.put("SUB_TABLE_NAME",category.getFileTableName());
                yqda.setTableName(new TenantYqda().getTableName());
                yqda.setColNames(map);
                yqdaMapper.insertYqda(yqda);
                if("2".equals(jsType)){
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.TEXT导入);
                }else if("6".equals(jsType)){
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.MDB导入);
                }else{
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.XML导入);
                }
            }else if("v".equals(type)){
                if(StringUtils.isNotEmpty(map.get("DH"))){
                    Integer count = folderMapper.getCountByCol("DH",map.get("DH"),category.getFolderTableName());
                    if(count>0){
                        msg.append("档号重复:"+map.get("DH")+"已跳过;");
                        continue;
                    }
                }
                TenantYqFolder folder = new TenantYqFolder();
                folder.setColNames(map);
                //插入分表
                folder.setTableName(category.getFolderTableName());
                folderMapper.insertYqFolderDisperse(folder);
                //插入主表
                String ID = map.get("ID");
                map.remove("ID");
                map.put("FOLDER_ID",ID);
                map.put("SUB_TABLE_NAME",category.getFolderTableName());
                folder.setTableName(new TenantYqFolder().getTableName());
                folder.setColNames(map);
                folderMapper.insertYqFolder(folder);
                if("2".equals(jsType)){
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.TEXT导入);
                }else if("6".equals(jsType)){
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.MDB导入);
                }else{
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.XML导入);
                }
            }else if("x".equals(type)){
                /*if(StringUtils.isNotEmpty(map.get("DH"))){
                    Integer count = itemMapper.getCountByCol("DH",map.get("DH"),category.getItemTableName());
                    if(count>0){
                        continue;
                    }
                }*/
                TenantYqItem item = new TenantYqItem();
                item.setColNames(map);
                //插入分表
                item.setTableName(category.getItemTableName());
                itemMapper.insertItemDisperse(item);
                //插入主表
                String ID = map.get("ID");
                map.remove("ID");
                map.put("ITEM_ID",ID);
                map.put("SUB_TABLE_NAME",category.getItemTableName());
                item.setTableName(new TenantYqItem().getTableName());
                item.setColNames(map);
                itemMapper.insertItem(item);
                if("2".equals(jsType)){
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.TEXT导入);
                }else if("6".equals(jsType)){
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.MDB导入);
                }else{
                    BusinessBehaviorUtil.add(Long.valueOf(ID), BusinessBehavior.XML导入);
                }
            }
            if("v".equals(type) && category.getType() == 3 && StringUtils.isNotEmpty(map.get("XMBH"))){
                //导入的是项目下卷层
                Long itemId = yqdaMapper.getFolderId("XMBH",map.get("XMBH"),category.getItemTableName());  //获取对应卷id
                if(itemId != null){
                    TenantItemFolder itemFolder = new TenantItemFolder();
                    itemFolder.setItemId(itemId);
                    itemFolder.setFolderId(Long.valueOf(map.get("FOLDER_ID")));
                    folderMapper.addItemFolder(itemFolder);
                }
            }

            if("f".equals(type) && category.getType()!=0 && StringUtils.isNotEmpty(map.get("DH"))){
                //通过RQ字段判断使用的档号规则
                String rqStr = map.get("RQ");
                Map<String,String> rule = null;
                if(StringUtils.isNotEmpty(rqStr)){
                    //日期处理成8位
                    rqStr = rqStr.replace("-","").replace("/","").replace(".","").replace(":","").replace(" ","").trim();
                    Integer rq = null;
                    if(rqStr.length()>8){
                        rq = Integer.valueOf(rqStr.substring(0,8));
                    }else if(rqStr.length()<8){
                        rq = Integer.valueOf((rqStr+("00000000".substring(0,8-rqStr.length()))));
                    }else {
                        rq = Integer.valueOf(rqStr);
                    }
                    rule = codeListMapper.getCodeListByRq(category.getId(),new TenantCodeList().getTableName(),new TenantCodeRule().getTableName(),rq);
                }
                if(rule == null || rule.size()==0){
                    //使用默认档号规则
                    rule = codeListMapper.getCodeListByRq(category.getId(),new TenantCodeList().getTableName(),new TenantCodeRule().getTableName(),null);
                }
                if(rule !=null && rule.size()>0){
                    String jianDh = rule.get("F_COLUMNNAME"); //件档号字段
                    String juanDh = rule.get("V_COLUMNNAME"); //卷档号字段
                    String lastNode = rule.get("NODE_VALUE"); //卷和件的连接符号
                    String dhValue = map.get(jianDh);
                    if(!StringUtils.isEmpty(dhValue)){
                        dhValue = dhValue.substring(0,dhValue.lastIndexOf(lastNode));  //截取出卷的档号
                        Long folderId = yqdaMapper.getFolderId(juanDh,dhValue,category.getFolderTableName());  //获取对应卷id
                        if(folderId != null){
                            TenantYqdaFolder yqdaFolder = new TenantYqdaFolder();
                            yqdaFolder.setFolderId(folderId);
                            yqdaFolder.setDaId(Long.valueOf(map.get("DA_ID")));
                            yqdaMapper.addYqdaFolder(yqdaFolder);
                        }
                    }
                }
            }
            num++;
        }
        return num;
    }
}
